package br.com.jspl.app.devices;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.io.Serializable;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import br.com.jspl.app.ui.AcaoButton;

public abstract class Componente extends JLabel implements Serializable{
   	 private AcaoButton botao;
   	 private String nome;
   	 protected Image Icone,img;
   	 private Toolkit tk;
   	 protected conexao[] EntradasSaidas;
   	 private Point PInicioComponente; 
   	 protected boolean Cusorpadrao;
     //private PonteiroMouse Ponteiro;
   	 protected ProtoBoard protoboard;
     private ComponenteAction acao;
   	 
     public Componente(String nomeComp, String nomedaImg,String nomedoIcone ,ProtoBoard p) {
    	 super(new ImageIcon(Componente.class.getClassLoader().getResource("br/com/jspl/imagens/" + nomedaImg)));
    	 tk = Toolkit.getDefaultToolkit();      
    	 setNome(nomeComp);
    	 //Abrir os arquivos das imagens        
    	 img= tk.getImage(getClass().getClassLoader().getResource("br/com/jspl/imagens/" + nomedaImg));  
    	 Icone = tk.getImage(getClass().getClassLoader().getResource("br/com/jspl/imagens/" + nomedoIcone));
    	 setCusorpadrao();    
    	 acao = new ComponenteAction(nomeComp,new ImageIcon(Icone),this);
    	 criaBotao();
    	 setProtoboard(p);
   	 }
     
   	 public Componente () {
   		 
   	 }

   	 public AcaoButton getBotao() {
   		 return botao; 
   	 }
 	public void criaBotao()
 	{
      botao = new AcaoButton(acao,false);
    }
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public Image getIcone() {
		return Icone;
	}
	public void setIcone(Image icone) {
		Icone = icone;
	}   	
	public Image getImagem()
	{
		return img;
	}
	public boolean fuiClicado(ProtoBoard pb, MouseEvent evt) {		
		Point PosicaoM= new Point(	evt.getPoint());					
		PosicaoM.x =((int)PosicaoM.getX()/8);
		PosicaoM.y = ((int)PosicaoM.getY()/8);
		setPInicioComponente(PosicaoM); 
		Circuito c=pb.getCircuitoAtual();
		c.adicionaComponete(this);
		pb.add(this);
		addMouseListener(pb);
		addMouseMotionListener(pb);
		setBounds( PInicioComponente.x*8,PInicioComponente.y*8,img.getWidth(null),img.getHeight(null));	
		pb.repaint();
		return true;
	}
	public void fuiCarregado()
	{
		protoboard.add(this);
		
		addMouseListener(protoboard);
		addMouseMotionListener(protoboard);
		setBounds( PInicioComponente.x*8,PInicioComponente.y*8,img.getWidth(null),img.getHeight(null));
		protoboard.repaint();
		
	}
	
	//Essa variavel tem por funo estabelcer o funcionamento do mouse, caso ela seja true
	//o componente usa cursores padrao ao inves de imagens
	public boolean isCusorpadrao() {
		return Cusorpadrao;
	}
	private void setCusorpadrao() {
		Cusorpadrao = false;
	}
	public Cursor getCursorpadrao()
	{
		return null;
	}
	public abstract Componente NovoComp();
	public void desenhar(Graphics g)
	{		
		
		Point w;
		for (int i=0 ; i< EntradasSaidas.length ;i++)
		{
			w = new Point(EntradasSaidas[i].getPontonoGride());
			w.x += PInicioComponente.x;
			w.y += PInicioComponente.y;	
			g.setColor(Color.red);
			g.drawOval(w.x*8,w.y*8,4,6);
			
		}
		g.setColor(Color.black);
		
	}
	public void CriarEntradasSaidas(int numE, int numS)
	{
		EntradasSaidas = new conexao[numE+numS];
	}
	public void setComponenteLigadoConexao(int x, Componente c)
	{
		EntradasSaidas[x].setCompLigado(c);
	}
	
	/**
	 * Retorno o componente para qual a conexo esta apontada. 
	 */			
	public Componente ComponenteLigadoConexao(int x)
	{
		return EntradasSaidas[x].getCompLigado();
	}
	/**
	 * Retorna o index da conexao ou -1 se no achou
	 */
	
	public int ExisteConexao(Point p)
	{
		Point w = new Point(p);
		w.x -= PInicioComponente.x;
		w.y -= PInicioComponente.y;
		Point PEntrada;
		//Procura pelo ponto no lugar exato
		for (int i=0 ; i< EntradasSaidas.length ;i++)
		{
			PEntrada =EntradasSaidas[i].getPontonoGride() ; 
			if ((PEntrada.x == w.x) || (PEntrada.x+1 ==w.x) || (PEntrada.x-1 ==w.x) )					
					if ((PEntrada.y == w.y)|| (PEntrada.y+1 ==w.y) || (PEntrada.y+1 ==w.y) )
					{
						if (EntradasSaidas[i].isVazio()) return  i;
						else 
						{
							JOptionPane.showMessageDialog(protoboard,"O Componente j possu cabo nesste ponto. ");
							return -1;
						}
					}
		}	
		return -1;
	}
	public Point getPInicioComponente() {
		return PInicioComponente;
	}
	public void setPInicioComponente(Point inicioComponente) {
		PInicioComponente = inicioComponente;
	}
	public void AtivarComponente() {
		Cabo c;
		boolean podeAtualizar= true;
		for (int i=0 ; i< EntradasSaidas.length ;i++) {
			c = (Cabo) ComponenteLigadoConexao(i);
			if (EntradasSaidas[i].getTipo() == 1) {
				if(!c.isAtualizado()) {
					podeAtualizar = false;
				} 
				else {
					EntradasSaidas[i].setEstado(c.getEstado());
				}
			}
			else				
			  if( podeAtualizar) c.setEstado(Resultado());	
		}
	}
	protected abstract boolean Resultado();
	public ComponenteAction getAcao() {
		return acao;
	}
	public void setAcao(ComponenteAction acao) {
		this.acao = acao;
	}
	public ProtoBoard getProtoboard() {
		return protoboard;
	}
	public void setProtoboard(ProtoBoard protoboard) {
		this.protoboard = protoboard;
	}
	public void deletar()
	{
		
		for (int i=0 ; i< EntradasSaidas.length ;i++)
			{
			if (EntradasSaidas[i].getTipo() == 1)	
			{					
				Circuito c=protoboard.getCircuitoAtual();
				c.removeComponente(this);					
				c.removeComponente ((EntradasSaidas[i]).getCompLigado());
			}
			}
	  protoboard.remove(this);
	}
	public conexao[] getEntradasSaidas() {
		return EntradasSaidas;
	}
	public void setEntradasSaidas(conexao[] entradasSaidas) {
		EntradasSaidas = entradasSaidas;
	}
}

